import { ActionTree } from 'vuex'
import { RouteLocationNormalized } from 'vue-router'
import { RootState } from '../index'

export interface TagView extends Partial<RouteLocationNormalized> {
  title?: string
}

export interface TagsViewState {
  visitedViews: TagView[]
  cachedViews: (string | undefined)[]
}

export const state: TagsViewState = {
  visitedViews: [],
  cachedViews: []
}

const mutations = {
  ADD_VISITED_VIEW: (state: TagsViewState, view: TagView) => {
    if (state.visitedViews.some((v) => v.path === view.path)) return
    state.visitedViews.push(
      Object.assign({}, view, {
        title: view.meta?.title ?? 'no-name'
      })
    )
  },
  ADD_CACHED_VIEW: (state: TagsViewState, view: TagView) => {
    if (state.cachedViews.includes(String(view.name))) return
    if (!view.meta?.noCache) {
      state.cachedViews.push(String(view.name))
    }
  },
  DEL_VISITED_VIEW: (state: TagsViewState, view: TagView) => {
    for (const [i, v] of state.visitedViews.entries()) {
      if (v.path === view.path) {
        state.visitedViews.splice(i, 1)
        break
      }
    }
  },
  DEL_CACHED_VIEW: (state: TagsViewState, view: TagView) => {
    const index = state.cachedViews.indexOf(String(view.name))
    index > -1 && state.cachedViews.splice(index, 1)
  }
}

const actions: ActionTree<TagsViewState, RootState> = {
  addView({ dispatch }, view) {
    dispatch('addVisitedView', view)
    dispatch('addCachedView', view)
  },
  addVisitedView({ commit }, view) {
    commit('ADD_VISITED_VIEW', view)
  },
  addCachedView({ commit }, view) {
    commit('ADD_CACHED_VIEW', view)
  },
  delView({ dispatch, state }, view) {
    return new Promise((resolve) => {
      dispatch('delVisitedView', view)
      dispatch('delCachedView', view)
      resolve({
        visitedViews: [...state.visitedViews],
        cachedViews: [...state.cachedViews]
      })
    })
  },
  delVisitedView({ commit, state }, view) {
    return new Promise((resolve) => {
      commit('DEL_VISITED_VIEW', view)
      resolve([...state.visitedViews])
    })
  },
  delCachedView({ commit, state }, view) {
    return new Promise((resolve) => {
      commit('DEL_CACHED_VIEW', view)
      resolve([...state.cachedViews])
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
